package SGEngine

import (
	//"fmt"
	gl "github.com/gl"
)

const (
	Horizontal = iota
	Vertical
)

type Label struct {
	Node
	Color     Color3
	LabelFont *Font
	Text      string
	//Chars     []*FontChar
	PaddingX float32
	PaddingY float32

	VBuffer   gl.Buffer
	TexBuffer gl.Buffer
	MProgram  *Program
}

func CreateLabel(_text string) *Label {

	lab := new(Label)
	lab.Color = WhiteColor
	lab.LabelFont = DefaultFont
	lab.Node = DefaultNode()
	lab.SetSizeV(VecOne)
	lab.NodeRender = lab

	lab.VBuffer = gl.GenBuffer()
	lab.TexBuffer = gl.GenBuffer()
	lab.SetText(_text)
	lab.MProgram = ACProgramMgr.GetProgram(PROGRAM_IMG)

	uniformTexture := lab.MProgram.ProgramObject.GetUniformLocation("s_texture")
	uniformTexture.Uniform1i(0)

	return lab
}
func (l *Label) SetText(_str string) {
	l.Text = _str
	l.FillVertexBuffer()
	l.SetSize(l.GetHalfWidth()*2, float64(l.LabelFont.BMFontData.Size), 1)

}
func (l *Label) GetHalfWidth() float64 {
	var RWidth float64
	RWidth = 0
	for _, V := range l.Text {
		glyph := l.LabelFont.BMFontData.GetTextByRune(V)
		if glyph != nil {
			RWidth += float64(glyph.Advance)
		}
	}
	return RWidth * 0.5
}

func (l *Label) FillVertexBuffer() {
	var PosX, PosY float64
	SizeOne := 1.0 / float64(l.LabelFont.BMFontData.Size)
	SizeXone := 1.0 / (l.GetHalfWidth() * 2)
	PosX = SizeXone * (-l.GetHalfWidth())
	PosY = SizeOne * (float64(l.LabelFont.BMFontData.LineHeight / 2))
	StrLen := len([]rune(l.Text))

	arrayBuffer := make([]float64, StrLen*18)
	TexBuffer := make([]float64, StrLen*12)
	i := 0
	j := 0

	for _, V := range l.Text {
		glyph := l.LabelFont.BMFontData.GetTextByRune(V)
		if glyph != nil {
			XP := SizeXone * float64(glyph.OffsetX)
			YP := -SizeOne * float64(glyph.OffserY)

			MinX := 0 + PosX + XP
			MaxX := float64(glyph.Width)*SizeXone + PosX + XP
			MinY := -float64(glyph.Height)*SizeOne + YP + PosY
			MaxY := 0 + YP + PosY
			//v0
			arrayBuffer[i] = MinX
			arrayBuffer[i+1] = MinY
			arrayBuffer[i+2] = 0
			//v1
			arrayBuffer[i+3] = MaxX
			arrayBuffer[i+4] = MinY
			arrayBuffer[i+5] = 0
			//v2
			arrayBuffer[i+6] = MinX
			arrayBuffer[i+7] = MaxY
			arrayBuffer[i+8] = 0
			//v3
			arrayBuffer[i+9] = MaxX
			arrayBuffer[i+10] = MinY
			arrayBuffer[i+11] = 0
			//v4
			arrayBuffer[i+12] = MaxX
			arrayBuffer[i+13] = MaxY
			arrayBuffer[i+14] = 0
			//v5
			arrayBuffer[i+15] = MinX
			arrayBuffer[i+16] = MaxY
			arrayBuffer[i+17] = 0
			i += 18
			TMinX := float64(glyph.X) / float64(l.LabelFont.BMFontData.ScaleW)
			TMaxX := float64(glyph.X+glyph.Width) / float64(l.LabelFont.BMFontData.ScaleW)
			TMaxY := float64(l.LabelFont.BMFontData.ScaleH-glyph.Y) / float64(l.LabelFont.BMFontData.ScaleH)
			TMinY := float64(l.LabelFont.BMFontData.ScaleH-glyph.Y-glyph.Height) / float64(l.LabelFont.BMFontData.ScaleH)
			//tv0
			TexBuffer[j] = TMinX
			TexBuffer[j+1] = TMinY
			//tv1
			TexBuffer[j+2] = TMaxX
			TexBuffer[j+3] = TMinY
			//tv2
			TexBuffer[j+4] = TMinX
			TexBuffer[j+5] = TMaxY
			//tv3
			TexBuffer[j+6] = TMaxX
			TexBuffer[j+7] = TMinY
			//tv4
			TexBuffer[j+8] = TMaxX
			TexBuffer[j+9] = TMaxY
			//tv5
			TexBuffer[j+10] = TMinX
			TexBuffer[j+11] = TMaxY
			j += 12
			PosX += SizeXone * float64(glyph.Advance)
		}
	}

	l.VBuffer.Bind(gl.ARRAY_BUFFER)
	gl.BufferData(gl.ARRAY_BUFFER, StrLen*18*4, arrayBuffer, gl.STATIC_DRAW)
	l.TexBuffer.Bind(gl.ARRAY_BUFFER)
	gl.BufferData(gl.ARRAY_BUFFER, StrLen*12*4, TexBuffer, gl.STATIC_DRAW)

}

func (l *Label) Render() {
	gl.Enable(gl.BLEND)
	gl.BlendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA)
	//gl.Enable(gl.ALPHA_TEST)
	//gl.AlphaFunc(gl.GREATER, 0.1)
	gl.Enable(gl.TEXTURE_2D)
	gl.ActiveTexture(gl.TEXTURE0)
	l.LabelFont.BMFontData.FontTexture.TexID.Bind(gl.TEXTURE_2D)
	l.MProgram.ProgramObject.Use()
	l.MProgram.ProgramObject.GetUniformLocation("inColor").Uniform4f(l.Color.R, l.Color.G, l.Color.B, 1)
	l.VBuffer.Bind(gl.ARRAY_BUFFER)
	l.MProgram.ProgramObject.GetAttribLocation("vPosition").AttribPointer(3, gl.FLOAT, false, 0, nil)
	l.MProgram.ProgramObject.GetAttribLocation("vPosition").EnableArray()
	l.TexBuffer.Bind(gl.ARRAY_BUFFER)
	l.MProgram.ProgramObject.GetAttribLocation("a_texCoord").AttribPointer(2, gl.FLOAT, false, 0, nil)
	l.MProgram.ProgramObject.GetAttribLocation("a_texCoord").EnableArray()
	CharLen := len([]rune(l.Text))

	gl.DrawArrays(gl.TRIANGLES, 0, CharLen*6)
	//gl.Disable(gl.ALPHA_TEST)
	gl.Disable(gl.BLEND)
	l.VBuffer.Unbind(gl.ARRAY_BUFFER)
	l.TexBuffer.Unbind(gl.ARRAY_BUFFER)
}
